package br.ufpb.di.ppgi.persistencia.query;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import br.com.caelum.vraptor.ioc.Component;
import br.ufpb.di.ppgi.negocio.modelo.homologacao.defesa.HomologacaoDefesa;
import br.ufpb.di.ppgi.negocio.modelo.homologacao.proposta.HomologacaoProposta;
import br.ufpb.di.ppgi.negocio.modelo.usuario.Usuario;
import br.ufpb.di.ppgi.negocio.modelo.usuario.UsuarioRole;
import br.ufpb.di.ppgi.negocio.servicos.login.Credencial;
import br.ufpb.di.ppgi.persistencia.domainstore.DomainStore;
import br.ufpb.di.ppgi.persistencia.iquery.IUsuarioQuery;
import br.ufpb.di.ppgi.persistencia.pagination.HibernateQueryPagedList;

@Component
public class UsuarioQuery extends AbstractJPAHibernateQuery implements IUsuarioQuery {

	public UsuarioQuery(DomainStore domainStore) {
		super(domainStore);
	}
	
	private Criteria blank() {
		return createCriteria(Usuario.class);
	}
	
	/* (non-Javadoc)
	 * @see br.ufpb.di.ppgi.persistencia.query.IUsuarioQuery#findByEmail(java.lang.String)
	 */
	public Usuario findByEmail(String email) {
		return unique(
			blank().add(Restrictions.eq("email", email))
		);
	}
	
	public Usuario findByCPF(String cpf) {
		return unique(
			blank().add(Restrictions.eq("cpf", cpf))
		);
	}
	
	/* (non-Javadoc)
	 * @see br.ufpb.di.ppgi.persistencia.query.IUsuarioQuery#findByCredential(br.ufpb.di.ppgi.negocio.servicos.login.Credencial)
	 */
	public Usuario findByCredential(Credencial credential) {
		Usuario usuario = findByEmail(credential.getLogin());
		return usuario != null && usuario.confirmaSenha(credential) ? usuario : null;
	}

	/* (non-Javadoc)
	 * @see br.ufpb.di.ppgi.persistencia.query.IUsuarioQuery#count()
	 */
	public Integer count() {
		return count(blank());
	}
	
	/* (non-Javadoc)
	 * @see br.ufpb.di.ppgi.persistencia.query.IUsuarioQuery#countSuperUser()
	 */
	public Integer countSuperUser() {
		return count(blank().add(Restrictions.eq("role", UsuarioRole.SU)));
	}	

	/* (non-Javadoc)
	 * @see br.ufpb.di.ppgi.persistencia.query.IUsuarioQuery#hasUsuarioByLogin(java.lang.String)
	 */
	public boolean hasUsuarioByLogin(String email) {
		return count(
				blank().add(Restrictions.eq("email", email))
		) > 0;
	}
	
	@Override
	public Usuario get(Long id) {
		return getDomainStore().get(Usuario.class, id);
	}

	@Override
	public List<Usuario> listAll() {
		return getDomainStore().list(Usuario.class,"role");
	}

	@Override
	public List<Usuario> listByRoles(List<UsuarioRole> roles) {
		return list(
			blank().add(Restrictions.in("role", roles))
		);
	}
	
	@Override
	public Integer qtdePendencias(Usuario colegiado) {
		return  count(
					createCriteria(HomologacaoProposta.class)
						.add(Restrictions.eq("pk.colegiado", colegiado))
						.add(Restrictions.eq("respondido", false))
						);
	}

	@Override
	public Integer qtdPropostasPendentes(Usuario colegiado) {
		return count(
				createCriteria(HomologacaoProposta.class)
				.add(Restrictions.eq("pk.colegiado", colegiado))
				.add(Restrictions.eq("respondido", false))
				);
	}

	@Override
	public Integer qtdDefesasPendentes(Usuario colegiado) {
		return count(
				createCriteria(HomologacaoDefesa.class)
				.add(Restrictions.eq("pk.colegiado", colegiado))
				.add(Restrictions.eq("respondido", false))
				);
	}

	@Override
	public Usuario fetchCoordenador() {
		return unique(
					blank().add(Restrictions.eq("role", UsuarioRole.COORDENADOR))
				);
	}
	
	@Override
	public void resetarSenha(Usuario usuario) {
		session.createQuery("UPDATE Usuario u SET u.senha=? WHERE u.id = ?")
				.setString(0, usuario.getSenha())
				.setLong(1, usuario.getId())
				.executeUpdate();
				
				
	}

	@Override
	public HibernateQueryPagedList<Usuario> paginarByKey(String key) {
		DetachedCriteria dc = DetachedCriteria.forClass(Usuario.class);
		
		if (key != null && !key.trim().isEmpty())
			dc.add(Restrictions.ilike("nome", key, MatchMode.ANYWHERE))
				.add(Restrictions.ilike("email", key, MatchMode.ANYWHERE))
				.add(Restrictions.ilike("emailPessoal", key, MatchMode.ANYWHERE));
				
		return new HibernateQueryPagedList<Usuario>(dc,session);
	}

	@Override
	public boolean cpfExists(String cpf) {
		return count(
					blank().add(Restrictions.eq("cpf", cpf))
				) > 0;
	}	
}
